package com.tuliyou.common.util;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 通用数据校验工具类
 * 包含：非空校验、长度校验、手机号/邮箱格式、用户名/密码规则等
 */
public class ValidationUtil {

    // 手机号正则：中国大陆手机号（11位，以1开头，第二位3-9，后9位数字）
    private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
    // 邮箱正则：支持字母、数字、下划线、中划线，域名支持多级
    private static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
    // 用户名正则：4-20位，仅包含字母、数字、下划线
    private static final String USERNAME_REGEX = "^[a-zA-Z0-9_]{4,20}$";
    // 密码正则：6-20位，至少包含大小写字母、数字、特殊字符（!@#$%^&*）中的三种
    private static final String PASSWORD_REGEX = "^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z!@#$%^&*]+$)(?![a-z0-9]+$)(?![a-z!@#$%^&*]+$)(?![0-9!@#$%^&*]+$).{6,20}$";

    /**
     * 非空校验（字符串会trim后判断）
     * @param str 待校验字符串
     * @param fieldName 字段名（用于错误提示）
     * @return 错误信息（null表示校验通过）
     */
    public static String checkNotNull(String str, String fieldName) {
        if (str == null || str.trim().isEmpty()) {
            return fieldName + "不能为空";
        }
        return null;
    }

    /**
     * 长度校验（字符串trim后）
     * @param str 待校验字符串
     * @param min 最小长度（包含）
     * @param max 最大长度（包含）
     * @param fieldName 字段名（用于错误提示）
     * @return 错误信息（null表示校验通过）
     */
    public static String checkLength(String str, int min, int max, String fieldName) {
        if (str == null) {
            return fieldName + "不能为空"; // 非空优先校验
        }
        String trimStr = str.trim();
        if (trimStr.length() < min || trimStr.length() > max) {
            return fieldName + "长度必须在" + min + "-" + max + "个字符之间";
        }
        return null;
    }

    /**
     * 手机号格式校验
     * @param phone 手机号
     * @return 错误信息（null表示校验通过）
     */
    public static String checkPhone(String phone) {
        // 先校验非空
        String notNullMsg = checkNotNull(phone, "手机号");
        if (notNullMsg != null) {
            return notNullMsg;
        }
        // 再校验格式
        if (!matches(phone.trim(), PHONE_REGEX)) {
            return "请输入正确的手机号格式（11位数字，以1开头）";
        }
        return null;
    }

    /**
     * 邮箱格式校验
     * @param email 邮箱
     * @return 错误信息（null表示校验通过）
     */
    public static String checkEmail(String email) {
        String notNullMsg = checkNotNull(email, "邮箱");
        if (notNullMsg != null) {
            return notNullMsg;
        }
        if (!matches(email.trim(), EMAIL_REGEX)) {
            return "请输入正确的邮箱格式（如xxx@xxx.com）";
        }
        return null;
    }

    /**
     * 用户名格式校验（4-20位，仅字母、数字、下划线）
     * @param username 用户名
     * @return 错误信息（null表示校验通过）
     */
    public static String checkUsername(String username) {
        String notNullMsg = checkNotNull(username, "用户名");
        if (notNullMsg != null) {
            return notNullMsg;
        }
        if (!matches(username.trim(), USERNAME_REGEX)) {
            return "用户名需为4-20位，仅包含字母、数字、下划线";
        }
        return null;
    }

    /**
     * 密码复杂度校验（6-20位，至少包含3种字符）
     * @param password 密码
     * @return 错误信息（null表示校验通过）
     */
    public static String checkPassword(String password) {
        String notNullMsg = checkNotNull(password, "密码");
        if (notNullMsg != null) {
            return notNullMsg;
        }
        if (!matches(password.trim(), PASSWORD_REGEX)) {
            return "密码需6-20位，且包含大小写字母、数字、特殊字符（!@#$%^&*）中的至少三种";
        }
        return null;
    }

    /**
     * 校验密码是否包含用户名（忽略大小写）
     * @param username 用户名
     * @param password 密码
     * @return 错误信息（null表示校验通过）
     */
    public static String checkPasswordContainsUsername(String username, String password) {
        if (username == null || password == null) {
            return null; // 非空校验由其他方法处理
        }
        if (password.trim().toLowerCase().contains(username.trim().toLowerCase())) {
            return "密码不能包含用户名";
        }
        return null;
    }

    /**
     * 组合校验：注册场景（用户名+密码+邮箱+手机号）
     * @param username 用户名
     * @param password 密码
     * @param email 邮箱
     * @param phone 手机号
     * @return 所有错误信息（空列表表示校验通过）
     */
    public static List<String> validateRegister(String username, String password, String email, String phone) {
        List<String> errors = new ArrayList<>();
        // 逐个校验，收集所有错误
        addError(errors, checkUsername(username));
        addError(errors, checkPassword(password));
        if(email != null) {
            addError(errors, checkEmail(email));
        }
        if(phone != null) {
            addError(errors, checkPhone(phone));
        }
        addError(errors, checkPasswordContainsUsername(username, password));
        return errors;
    }

    // 内部工具：添加错误信息（非null才添加）
    private static void addError(List<String> errors, String errorMsg) {
        if (errorMsg != null) {
            errors.add(errorMsg);
        }
    }

    // 内部工具：正则匹配
    private static boolean matches(String str, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }

}